#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include <cstdio>
#include <vector>
#include <errno.h>
#include <cstring>
#include <string>

using namespace std;

// 使用多线程，模拟抢票一轮
#define NUM 4
int ticket = 1000;
class threadData
{
public:
    threadData(int num)
    {
        threadname = "thread-" + to_string(num);
    }
    static void *Getticket(void *args)
    {
        threadData *td = static_cast<threadData *>(args);
        const char *name = td->threadname.c_str();
        while (true)
        {
            if (ticket > 0)
            {
                usleep(10000);
                printf("who:%s,get a ticket:%d\n", name, ticket);
                ticket--;
                usleep(10000);
            }
            else
            {
                break;
            }
        }
        printf("%s....quit\n", name);
        return nullptr;
    }

public:
    string threadname;
};

int main()
{
    vector<pthread_t> tids;
    vector<threadData *> datas;
    for (int i = 0; i < NUM; i++)
    {
        pthread_t tid;
        threadData *data = new threadData(i);
        datas.push_back(data);
        // 不能传&data,这是传递的是指针的地址，而不是threadData对象的地址
        pthread_create(&tid, nullptr, threadData::Getticket, data);
        tids.push_back(tid);
    }

    for (auto &thread : tids)
    {
        pthread_join(thread, nullptr);
    }
    for (auto td : datas)
    {
        delete (td);
    }
    return 0;
}

// #define NUM 20

// __thread int g_val = 100;

// class threadData
// {
// public:
//     threadData(int num)
//     {
//         threadname = "thread-" + to_string(num);
//     }

//     string toHex(pthread_t tid)
//     {
//         char buff[128];
//         snprintf(buff, sizeof(buff), "0x%x", tid);
//         return buff;
//     }

//     static void *threadRoutine(void *args)
//     {
//         // 转化参数为threadData指针
//         threadData *td = static_cast<threadData *>(args);
//         // 分离线程，避免内存泄漏
//         //  pthread_detach(pthread_self());
//         // 获取并格式化线程/进程信息
//         string tidStr = td->toHex(pthread_self());
//         int pid = getpid();
//         int cnt = 0;
//         while (cnt < 10)
//         {
//             // cout<<"tid: "<<tidStr<<",pid: "<<pid<<" ,pthreadname: "<<td->threadname<<endl;

//             cout << "new thread: " << "g_val: " << g_val << ", &g_val" << &g_val << endl;
//             sleep(1);
//             cnt++, g_val++;
//         }
//         // delete td;
//         return nullptr;
//     }

// public:
//     string threadname;
// };

// int main()
// {
//     // 创建新线程
//     vector<pthread_t> tids;
//     for (int i = 0; i < NUM; i++)
//     {
//         pthread_t tid;
//         // threadData data(1);
//         threadData data = threadData(1);
//         pthread_create(&tid, nullptr, threadData::threadRoutine, &data);
//         cout <<"main thread: "<< "g_val: " << g_val << ", &g_val" << &g_val << endl;
//         g_val++;
//         sleep(1);
//         tids.push_back(tid);
//     }
//     // sleep(1);

//     // 确保复制成功
//     sleep(1);

//     for (int i = 0; i < NUM; i++)
//     {
//         int n = pthread_join(tids[i], nullptr);
//         printf("n=%d,who:0x%x,why:%s\n", n, tids[i], strerror(n));
//     }
//     return 0;
// }

// void *threadRun(void *args)
// {
//     pthread_detach(pthread_self());
//     printf("%s\n",(char*)args);
//     return nullptr;
// }

// int main()
// {
//     pthread_t tid;
//     if(pthread_create(&tid,nullptr,threadRun,0)!=0)
//     {
//         printf("creat thread error\n");
//         return 1;
//     }
//     int ret=0;
//     sleep(1);  //让线程先分离，再等待，很重要？
//     if(pthread_join(tid,nullptr)==0)
//     {
//         printf("pthread wait success\n");
//         ret=0;
//     }
//     else
//     {
//         printf("pthread wait fail\n");
//         return 1;
//     }
//     return ret;
// }